home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / Collection.C < prev    next >
C/C++ Source or Header  |  1990-12-06  |  8KB  |  469 lines

  1. //$Collection,DeletedObject,CollFilterIter$
  2. #include "Error.h"
  3. #include "Collection.h"
  4. #include "OrdColl.h"
  5. #include "ObjArray.h"
  6. #include "Set.h"
  7. #include "Bag.h"
  8. #include "ObjList.h"
  9. #include "SortedOList.h"
  10. #include "String.h"
  11.     
  12. Collection *pCurrentCollection;
  13. char *cNullPointerWarning= "called with 0";
  14.  
  15. AbstractMetaImpl(Collection, (T(size), T(nDeleted), T(iterCount), 0));
  16.  
  17. Collection::Collection()
  18. {
  19.     size= 0;
  20.     iterCount= 0;
  21.     nDeleted= 0;
  22. }
  23.  
  24. Collection::~Collection()
  25. {
  26.     if (iterCount && gDebug) 
  27.     Warning("~Collection", "%s deleted while there is an active iterator",
  28.                                 ClassName());
  29. }
  30.  
  31. bool Collection::assertclass(Class *cl)
  32. {
  33.     register ObjPtr op;
  34.     Iter next(this);
  35.     bool error= FALSE;
  36.  
  37.     if (cl == 0) {
  38.     Error("assertclass", "class == 0");
  39.     return TRUE;
  40.     }
  41.     for (int i= 0; op= next(); i++)
  42.     if (! op->IsA()->isKindOf(cl)) {
  43.         Error("assertclass", "element %d is not instance of class %s (%s)", i,
  44.                         cl->Name(), op->ClassName());
  45.         error= TRUE;
  46.     }
  47.     return error;
  48. }
  49.  
  50. void Collection::InspectorId(char *b, int sz)
  51. {
  52.     if (Size() && !IsKindOf(Set) && At(0) && sz > 10) {
  53.     char *firstClass= At(0)->ClassName();
  54.     if (firstClass && strlen(firstClass) + 20 < sz) 
  55.         sprintf(b, "<%s> [%d]", firstClass, Size());
  56.     else
  57.         sprintf(b, "[%d]", Size()); 
  58.     }
  59.     else
  60.     sprintf(b, "[%d]", Size());   
  61. }
  62.  
  63. ObjPtr Collection::Add(ObjPtr) 
  64. {
  65.     AbstractMethod("Add");
  66.     return 0;
  67. }
  68.  
  69. void Collection::AddVector(ObjPtr va_(op1), ...) 
  70. {
  71.     va_list ap;    
  72.     va_start(ap,va_(op1));
  73.     register Object *op;
  74.     
  75.     Add(va_(op1));
  76.     while (op= va_arg(ap, Object*))
  77.     Add(op);
  78.     va_end(ap);
  79. }
  80.  
  81. void Collection::AddVector(va_list ap) 
  82. {
  83.     register Object *op;
  84.     
  85.     while (op= va_arg(ap, Object*))
  86.     Add(op);
  87. }
  88.  
  89. ObjPtr Collection::Remove(ObjPtr)
  90. {
  91.     AbstractMethod("Remove");
  92.     return 0;
  93. }
  94.  
  95. ObjPtr Collection::RemovePtr(ObjPtr)
  96. {
  97.     AbstractMethod("RemovePtr");
  98.     return 0;
  99. }
  100.  
  101. void Collection::RemoveDeleted()
  102. {
  103. }
  104.  
  105. ObjPtr Collection::Clone()
  106. {
  107.     Collection *newcoll= (Collection*) New();
  108.  
  109.     newcoll->AddAll(this);
  110.     return newcoll;
  111. }
  112.  
  113. void Collection::AddAll(CollPtr Coll)
  114. {
  115.     Iter next(Coll);
  116.     register ObjPtr op;
  117.  
  118.     while (op = next())
  119.     Add (op);
  120. }
  121.  
  122. void Collection::RemoveAll(CollPtr Coll)
  123. {
  124.     Iter next(Coll);
  125.     register ObjPtr op;
  126.  
  127.     while (op = next())
  128.     Remove(op);
  129. }
  130.  
  131. void Collection::FreeAll()
  132. {
  133.     Iter next(this);
  134.     register ObjPtr op;
  135.  
  136.     while (op= next())
  137.     if (op= Remove(op)) {
  138.         op->FreeAll();
  139.         delete op;
  140.     }
  141.     int size= 0;
  142. }
  143.  
  144. void Collection::Empty(int)
  145. {
  146.     Iter next(this);
  147.     register ObjPtr op;
  148.  
  149.     while (op= next())
  150.     Remove(op);
  151. }
  152.  
  153. bool Collection::Contains(ObjPtr anOp)
  154. {
  155.     return Find(anOp) != 0;
  156. }
  157.  
  158. bool Collection::ContainsPtr(ObjPtr anOp)
  159. {
  160.     return FindPtr(anOp) != 0;
  161. }
  162.  
  163. ObjPtr Collection::Find(ObjPtr anOp)
  164. {
  165.     register ObjPtr op;
  166.  
  167.     if (anOp == 0)
  168.     return 0;
  169.     Iter next(this);
  170.  
  171.     while (op = next()) 
  172.     if (op->IsEqual (anOp))
  173.         return op;
  174.     return 0;   
  175. }
  176.  
  177. ObjPtr Collection::FindPtr(ObjPtr anOp)
  178. {
  179.     register ObjPtr op;
  180.  
  181.     if (anOp == 0)
  182.     return 0;
  183.     Iter next(this);
  184.  
  185.     while (op = next()) 
  186.     if (op == anOp)
  187.         return op;
  188.     return 0;   
  189. }
  190.  
  191. ObjPtr Collection::At(int pos)
  192. {
  193.     Iter next(this);
  194.     register ObjPtr op;
  195.  
  196.     for (int i= 0; op= next(); i++) 
  197.     if (i == pos)
  198.         break;
  199.     if (op == 0) {
  200.     Error ("At", cOutOfBoundsError);
  201.     return 0;
  202.     }
  203.     return op;   
  204. }
  205.  
  206. Iterator *Collection::MakeIterator()
  207. {
  208.     AbstractMethod("Iterator");
  209.     return 0;
  210. }
  211.  
  212. bool Collection::IsEqual(ObjPtr col)
  213. {
  214.     if (IsA() != col->IsA())
  215.     return FALSE;
  216.  
  217.     Iter next1(this), next2((CollPtr)col);
  218.     register ObjPtr op1, op2;
  219.  
  220.     for (;;) {
  221.     op1 = next1();
  222.     op2 = next2();
  223.     if (op1 == 0 && op2 == 0)
  224.         return TRUE;
  225.     if (op1 == 0 || op2 == 0) 
  226.         break;
  227.     if (! op1->IsEqual(op2))
  228.         break;
  229.     }
  230.     return FALSE;
  231. }
  232.  
  233. unsigned long Collection::Hash()
  234. {
  235.     Iter next(this);
  236.     register ObjPtr op;
  237.     register unsigned long s= 0;
  238.  
  239.     while (op= next())
  240.     s^= op->Hash();
  241.     return s;   
  242. }
  243.  
  244. int Collection::OccurrencesOf(ObjPtr anOp)
  245. {
  246.     register ObjPtr op;
  247.     register int n = 0;
  248.  
  249.     if (anOp == 0)
  250.     return 0;
  251.     Iter next(this);
  252.     while (op = next()) 
  253.     if (op->IsEqual (anOp))
  254.         n++;
  255.     return n;   
  256. }
  257.  
  258. int Collection::OccurrencesOfPtr(ObjPtr anOp)
  259. {
  260.     register ObjPtr op;
  261.     register int n = 0;
  262.  
  263.     if (anOp == 0)
  264.     return FALSE;
  265.     Iter next(this);
  266.     while (op = next()) 
  267.     if (op == anOp)
  268.         n++;
  269.     return n;   
  270. }
  271.  
  272. CollPtr Collection::Collect(ObjPtrFun fp,void* Arg)
  273. {
  274.     Iter next(this);
  275.     register ObjPtr op;
  276.     register CollPtr cp = (CollPtr) New();    
  277.  
  278.     while (op = next())
  279.     cp->Add ((*fp)(this,op,Arg)); 
  280.     return cp;
  281. }
  282.  
  283. CollPtr Collection::Select(BoolFun fp,void *Arg)
  284. {
  285.     Iter next(this);
  286.     register ObjPtr op;
  287.     register CollPtr cp = (CollPtr) New();    
  288.  
  289.     while (op = next())
  290.     if ((*fp)(this,op,Arg))
  291.         cp->Add (op); 
  292.     return cp;
  293. }
  294.  
  295. ObjPtr Collection::Detect(BoolFun fp,void *Arg)
  296. {
  297.     Iter next(this);
  298.     register ObjPtr op, detectedOp = 0;
  299.  
  300.     while (op = next())
  301.     if ((*fp)(this,op,Arg)) {
  302.         detectedOp = op;
  303.         break;
  304.     }
  305.     return detectedOp;
  306. }
  307.  
  308. void Collection::EnterIter()
  309. {
  310.     iterCount++;
  311. }
  312.  
  313. void Collection::ExitIter()
  314. {
  315.     iterCount--;
  316.     if (iterCount == 0 && nDeleted) {
  317.     RemoveDeleted();
  318.     nDeleted= 0;
  319.     }
  320.     else if (iterCount < 0)
  321.     iterCount= 0;
  322. }
  323.  
  324. void Collection::CheckActiveIter(char *where)
  325. {
  326.     if (InIterator())
  327.     Warning(where, "iterator is still active");    
  328. }
  329.  
  330. int Collection::GrowBy(int desiredSize)
  331. {
  332.     int s= 0;
  333.     if (Size() >= cMaxInt)
  334.     Error("GrowBy", "cannot expand collection");
  335.     else
  336.     s= range(2, cMaxInt - desiredSize, desiredSize);
  337.     return Size()+s;
  338. }
  339.  
  340. class OrdCollection *Collection::AsOrderedCollection()
  341. {
  342.     OrdCollection *oc= new OrdCollection(Size());
  343.  
  344.     oc->AddAll(this);
  345.     return oc;
  346. }
  347.  
  348. class ObjArray *Collection::AsObjArray()
  349. {
  350.     register ObjArray *oa = new ObjArray(Size());
  351.     Iter next(this);
  352.     register ObjPtr op;
  353.  
  354.     for (int i= 0; op = next(); i++)
  355.     oa->AtPut(i, op);
  356.     return oa;
  357. }
  358.  
  359. class Bag *Collection::AsBag()
  360. {
  361.     Bag *bp = new Bag(Size());
  362.  
  363.     bp->AddAll(this);
  364.     return bp;
  365. }
  366.  
  367. class Set *Collection::AsSet()
  368. {
  369.     Set *sp = new Set(Size());
  370.  
  371.     sp->AddAll(this);
  372.     return sp;
  373. }
  374.  
  375. class ObjList *Collection::AsObjList()
  376. {
  377.     ObjList *ol = new ObjList;
  378.  
  379.     ol->AddAll(this);
  380.     return ol;
  381. }
  382.  
  383. class SortedObjList *Collection::AsSortedObjList(bool ascending)
  384. {
  385.     SortedObjList *sl = new SortedObjList(ascending);
  386.  
  387.     sl->AddAll(this);
  388.     return sl;
  389. }
  390.  
  391. ostream& Collection::PrintOn (ostream& s)
  392. {
  393.     register ObjPtr op;
  394.     Iter next(this);
  395.     int sz;
  396.  
  397.     Object::PrintOn(s);
  398.     s << Size() SP;
  399.     for (sz= 0; op = next(); sz++)
  400.     if (!op->IsDeleted())
  401.         s << op SP;
  402.     return s NL;
  403. }
  404.  
  405. ostream& Collection::DisplayOn(ostream &s)
  406. {
  407.     register ObjPtr op;
  408.     Iter next(this);
  409.  
  410.     while (op= next()) {
  411.     op->DisplayOn(s);
  412.     s NL;
  413.     }
  414.     return s;
  415. }
  416.  
  417. istream& Collection::ReadFrom (istream& s)
  418. {
  419.     int sz;
  420.     ObjPtr op;
  421.  
  422.     Object::ReadFrom(s);
  423.     s >> sz;
  424.     for (int i= 0; i < sz; i++) {
  425.     s >> op;
  426.     Add(op);
  427.     }
  428.     return s;
  429. }
  430.  
  431. bool Collection::NullPointerWarning(char *where)
  432. {
  433.     Warning(where, cNullPointerWarning); 
  434.     return TRUE; 
  435. }
  436.  
  437. //---- class CollFilterIter ----------------------------------------------------
  438.  
  439. CollFilterIter::~CollFilterIter()
  440. {
  441.     SafeDelete(next);
  442. }
  443.  
  444. void CollFilterIter::Reset(Collection *s)
  445. {
  446.     next->Reset(s);
  447. }
  448.  
  449. ObjPtr CollFilterIter::operator()()
  450. {
  451.     register ObjPtr op;
  452.  
  453.     while (op = (*next)()) {
  454.     if (!filterFun)
  455.         break;
  456.     if (filterFun((ObjPtr)this,op,filterArg))
  457.         break;
  458.     }
  459.     return op;               
  460. }
  461.  
  462. //---- class DeletedObject -----------------------------------------------------
  463.  
  464. MetaImpl0(DeletedObject);
  465.  
  466. DeletedObject::DeletedObject() : Object(eObjIsDeleted)
  467. }
  468.